package com.sun.filesigndemo.common.security.Filter;


import com.sun.filesigndemo.common.security.Token.UsernamePasswordToken;
import com.sun.filesigndemo.common.utils.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Service;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
 * 表单验证（包含验证码）过滤类
 * @author Winkey
 * @version 2017-11-06
 */
@Service
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {

	public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
	public static final String DEFAULT_MOBILE_PARAM = "mobileLogin";
	public static final String DEFAULT_MESSAGE_PARAM = "message";

	private String captchaParam = DEFAULT_CAPTCHA_PARAM;
	private String mobileLoginParam = DEFAULT_MOBILE_PARAM;
	private String messageParam = DEFAULT_MESSAGE_PARAM;

//
//	@Override
//	protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
//		if(this.isLoginRequest(request, response)) {
//			if(this.isLoginSubmission(request, response)) {
//				return this.executeLogin(request, response);
//			} else {
//				return true;
//			}
//		} else {
//
//
//
//			String header = ((HttpServletRequest) request).getHeader("X-Requested-With");
//			if(header != null && header.equals("XMLHttpRequest")){
//				response.setCharacterEncoding("UTF-8");
//				PrintWriter out = response.getWriter();
//				out.print("{\"code\" : 704, \"message\" : \"请先登录\" }");
//				out.flush();
//				out.close();
//			}
//			return true;
//		}
//	}

	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		String username = getUsername(request);
		String password = getPassword(request);
		if (password==null){
			password = "";
		}
		boolean rememberMe = isRememberMe(request);
		String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
		String captcha = getCaptcha(request);
		boolean mobile = isMobileLogin(request);
		return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile);
	}
	
	/**
     * 获取请求Body
     *
     * @param request
     * @return
     */
    public static String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
	
	/**
	 * 获取登录用户名
	 */
	protected String getUsername(ServletRequest request, ServletResponse response) {
		String username = super.getUsername(request);
		if (StringUtils.isBlank(username)){
			username = StringUtils.toString(request.getAttribute(getUsernameParam()), StringUtils.EMPTY);
		}
		return username;
	}
	
	/**
	 * 获取登录密码
	 */
	@Override
	protected String getPassword(ServletRequest request) {
		String password = super.getPassword(request);
		if (StringUtils.isBlank(password)){
			password = StringUtils.toString(request.getAttribute(getPasswordParam()), StringUtils.EMPTY);
		}
		return password;
	}
	
	/**
	 * 获取记住我
	 */
	@Override
	protected boolean isRememberMe(ServletRequest request) {
		String isRememberMe = WebUtils.getCleanParam(request, getRememberMeParam());
		if (StringUtils.isBlank(isRememberMe)){
			isRememberMe = StringUtils.toString(request.getAttribute(getRememberMeParam()), StringUtils.EMPTY);
		}
		return StringUtils.toBoolean(isRememberMe);
	}

	public String getCaptchaParam() {
		return captchaParam;
	}

	protected String getCaptcha(ServletRequest request) {
		return WebUtils.getCleanParam(request, getCaptchaParam());
	}

	public String getMobileLoginParam() {
		return mobileLoginParam;
	}
	
	protected boolean isMobileLogin(ServletRequest request) {
        return WebUtils.isTrue(request, getMobileLoginParam());
    }
	
	public String getMessageParam() {
		return messageParam;
	}
	
	/**
	 * 登录成功之后跳转URL
	 */
	public String getSuccessUrl() {
		return super.getSuccessUrl();
	}
	
	@Override
	protected void issueSuccessRedirect(ServletRequest request,
			ServletResponse response) throws Exception {
//		Principal p = UserUtils.getPrincipal();
//		if (p != null && !p.isMobileLogin()){
			 //WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);

		//ajax 请求直接改为由系统转发
			 RequestDispatcher rd = getServletContext().getRequestDispatcher(getSuccessUrl());
			 rd.forward(request, response);
//		}else{
//			super.issueSuccessRedirect(request, response);
//		}
	}


//	@Override
//	protected void redirectToLogin(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
//		try {
//			HttpServletRequest request = (HttpServletRequest) servletRequest;
//			HttpServletResponse response = (HttpServletResponse) servletResponse;
//			String contentType = request.getContentType();
//			if (contentType != null && contentType.contains("application/json")) {
//				response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
//				response.setCharacterEncoding("UTF-8");
//				PrintWriter writer = response.getWriter();
//				writer.print("{\"error\":\"登录超时，请重新登录。\"}");
//			} else {
//				super.redirectToLogin(servletRequest, servletResponse);
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//			super.redirectToLogin(servletRequest, servletResponse);
//		}
//	}


//	   /**
//     * 当登录成功
//     * @param token
//     * @param subject
//     * @param request
//     * @param response
//     * @return
//     * @throws Exception
//     */
//    @Override
//    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
//
//
//        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
//        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//
//        if (!"XMLHttpRequest".equalsIgnoreCase(httpServletRequest
//                .getHeader("X-Requested-With"))) {// 不是ajax请求
//            issueSuccessRedirect(request, response);
//        } else {
//        		httpServletResponse.setContentType("application/json; charset=utf-8");
//            PrintWriter out = httpServletResponse.getWriter();
//            out.println("{\"success\":true,\"message\":\"登入成功\"}");
//            out.flush();
//            out.close();
//        }
//        return false;
//    }

	/**
	 * 登录失败调用事件
	 */
	@Override
	protected boolean onLoginFailure(AuthenticationToken token,
			AuthenticationException e, ServletRequest request, ServletResponse response) {
		String className = e.getClass().getName(), message = "";
		if (IncorrectCredentialsException.class.getName().equals(className)
				|| UnknownAccountException.class.getName().equals(className)){
			message = "用户或密码错误, 请重试.";
		}
		else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
			message = StringUtils.replace(e.getMessage(), "msg:", "");
		}
		else{
			message = "用户或密码错误, 请重试.";
//			message = "系统出现点问题，请稍后再试！";
			e.printStackTrace(); // 输出到控制台
		}
        request.setAttribute(getFailureKeyAttribute(), className);
        request.setAttribute(getMessageParam(), message);
        return true;
	}
	
}